package ca.etsmtl.log730.projet2.connectors.client.tcpip;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import ca.etsmtl.log730.projet2.connectors.AbstractSetup;
import ca.etsmtl.log730.projet2.connectors.client.ClientAdapter;
import ca.etsmtl.log730.projet2.connectors.msg.document.DocumentEVT;
import ca.etsmtl.log730.projet2.connectors.msg.document.DocumentEVT.ModType;
import ca.etsmtl.log730.projet2.connectors.msg.user.UserCMD;
import ca.etsmtl.log730.projet2.connectors.msg.user.UserEVT;
import ca.etsmtl.log730.projet2.connectors.msg.user.UserEVT.Action;
import ca.etsmtl.log730.projet2.documents.Document;
import ca.etsmtl.log730.projet2.users.User;

/*
 * BING BANG
 */
public class DistantClientAdapter implements ClientAdapter, IoHandler {
	
	/*
	 * Clone le contenu du Document|User Controller
	 */
	private Map<UUID, Document> documentMap = new HashMap<UUID, Document>();
	private Set<User> users = new HashSet<User>();
	
	@Override
	public void documentChanged(UUID id, Document doc) {
		documentMap.put(id, doc);
	}

	@Override
	public void documentAdded(UUID id, Document doc) {
		documentMap.put(id, doc);
	}

	@Override
	public void documentRemoved(UUID id, Document doc) {
		documentMap.remove(id);
	}

	@Override
	public void userJoined(User u) {
		users.add(u);
	}

	@Override
	public void userQuitted(User u) {
		users.remove(u);
	}


	@Override
	public void exceptionCaught(IoSession ios, Throwable arg1)
			throws Exception {
	}

	@Override
	public void messageReceived(IoSession io, Object o) throws Exception {
		System.out.println(o.toString());
		/*
		 * Évènement du +/- user
		 */
		if(o instanceof UserEVT) {
			UserEVT u = (UserEVT) o;
			if(u.getAction() == Action.JOINED) {
				//ADD PLAYER;
				userJoined(u.getUser());
			} else if(u.getAction() == Action.QUITTED) {
				//REMOVE PLAYER
				userQuitted(u.getUser());
			}
		} else if (o instanceof DocumentEVT) {
			DocumentEVT d = (DocumentEVT) o;
			if(d.getModType() == ModType.ADDED) {
				//ADD
				documentAdded(d.getDocId(), d.getDocument());
			} else if(d.getModType() == ModType.REMOVED) {
				//REMOVED
				documentRemoved(d.getDocId(), d.getDocument());
			} else if(d.getModType() == ModType.CHANGED) {
				//CHANGE
				documentChanged(d.getDocId(), d.getDocument());
			}
 		}
		/*
		 * EVENTS HANDLING
		 */
	}

	@Override
	public void messageSent(IoSession ios, Object arg1) throws Exception {
	}

	@Override
	public void sessionClosed(IoSession ios) throws Exception {
	}

	@Override
	public void sessionCreated(final IoSession ios) throws Exception {
		
		/*
		 * Bien important 
		 */
		new Thread(new Runnable() {

			@Override
			public void run() {
				
				ios.write(new UserCMD(UserCMD.Action.JOINING, getUser()));
			}
			
		}).start();
	}

	@Override
	public void sessionIdle(IoSession ios, IdleStatus arg1) throws Exception {
	}

	@Override
	public void sessionOpened(IoSession ios) throws Exception {
	
	}

	private User user = null;
	@Override
	public User getUser() {
		return user;
	}

	@Override
	public void setUser(User u) {
		user = u;
	}

	private AbstractSetup clientSetup;

	@Override
	public void close() {
		clientSetup.close();
	}

	@Override
	public void open(AbstractSetup cs) {
		clientSetup = cs;
//		clientSetup .setClientAdapter(this);
		clientSetup.open();
	}

}
